/*
use C++ to show the function "matrix_calc_taskB".
and the input parameter is "TaskMatrixInfoB**",which is the same as Guidance.
*/
#include <iostream>
using namespace std;

typedef struct {
	const double * 	valueSpiceMatrix;//N*2
	const int* 		rowOffset; 		//n+1
	const int* 		columnIndice; 	//N

	double* 		A;	//N
	double*		 	S;	//nx1
	double*			R;	//nx1
	double* 		H;	//nx1
	const double* 	D;	//N*2
	double* 		IC;	//nx1
	double* 		IG;	//nx1
	double 		alpha;
	int * 			rowArray; //kx1
	int 			rowArraySize;
	void* 			hdl;  //? what's this?
}TaskMatrixInfoB;
//Task B interface
void matrix_calc_taskB(TaskMatrixInfoB** listDataList,int N)
{
//(4)(5)
	for(int it = 0;it < (*listDataList)->rowArraySize;++it){
		int row = (*listDataList)->rowArray[it];

		for (int p = (*listDataList)->rowOffset[row];p < (*listDataList)->rowOffset[row + 1];++p){
			int col = (*listDataList)->columnIndice[p];
			const int k = p * 2;
			double cond =(*listDataList)->valueSpiceMatrix[k];
			double cap  =(*listDataList)->valueSpiceMatrix[k+1];

			(*listDataList)->IG[row] += cond * (*listDataList)->S[col];
			(*listDataList)->IC[row] += cap * (*listDataList)->S[col];
		} 
	} 
//(7)(8)
	for (int it = 0; it < (*listDataList)->rowArraySize;++it){
		int row = (*listDataList)->rowArray[it];
		const int k1 = row * 2;
		double current = (*listDataList)->D[k1];
		double charge = (*listDataList)->D[k1+1];

		for (int p = (*listDataList)->rowOffset[row];p<(*listDataList)->rowOffset[row+1];++p){
			int col = (*listDataList)->columnIndice[p];
			const int k = p*2;
			current -= (*listDataList)->valueSpiceMatrix[k] * (*listDataList)->S[col];
			charge -= (*listDataList)->valueSpiceMatrix[k+1]* (*listDataList)->S[col];
		}
		(*listDataList)->R[row] = current;
		(*listDataList)->H[row] = charge;
	}
//(9)
	for (int it = 0;it < (*listDataList)->rowArraySize;++it){
		int row = (*listDataList)->rowArray[it];
		for(int p = (*listDataList)->rowOffset[row];p < (*listDataList)->rowOffset[row+1];++p){
			const int k = p*2;
			double cond = (*listDataList)->valueSpiceMatrix[k];
			double cap = (*listDataList)->valueSpiceMatrix[k+1];
			(*listDataList)->A[p] = cond +  cap* (*listDataList)->alpha;
		}
	}
}

int main()
{
	TaskMatrixInfoB** listData;
	TaskMatrixInfoB* listData_temp=new TaskMatrixInfoB;
	listData = &listData_temp;

	double valueSpiceMatrix_[18]={1.0,0.5,2.2,0.3,3.5,0.1,0.3,0.7,9.2,4.2,2.3,7.5,6.9,1.2,0.2,1.0,7.3,5.6};
	(*listData)->valueSpiceMatrix=valueSpiceMatrix_;
	int rowOffset_[5] = {0,2,4,7,9};
	(*listData)->rowOffset=rowOffset_;
	int columnIndice_[9] = {0,1,1,2,0,2,3,0,3};
	(*listData)->columnIndice=columnIndice_;
	double A_[9]={1,5,8,3,5,2,4,9,1};
	(*listData)->A=A_;
	double S_[4]={3.5,2.5,4.5,1.5};
	(*listData)->S=S_;
	double R_[4]={0};
	(*listData)->R=R_;
	double H_[4]={0};
	(*listData)->H=H_;
	double D_[8]={1,1,1,1,1,1,1,1};
	(*listData)->D=D_;
	double IC_[4]={0};
	(*listData)->IC=IC_;
	double IG_[4]={0};
	(*listData)->IG=IG_;
	(*listData)->alpha=0.5;
	int rowArray_[4]={0,1,2,3};
	(*listData)->rowArray=rowArray_;
	(*listData)->rowArraySize = 4;

	matrix_calc_taskB(listData , 4);	

//show results:	

	for(int i=0;i<4;++i){
		cout << (*listData)->IG[i] <<" ";
	}
	cout<<"\n";
	
	for(int i=0;i<4;++i){
		cout << (*listData)->IC[i] <<" ";
	}
	cout<<"\n";
	
	for(int i=0;i<4;++i){
		cout << (*listData)->R[i] <<" ";
	}
	cout<<"\n";
	
	for(int i=0;i<4;++i){
		cout << (*listData)->H[i] <<" ";
	}
	cout<<"\n";
	
	delete(listData_temp); 
  	return 0;
}

